#define VECTOR_IMPLEMENTATION
#include "vector.hol.h"

#include <assert.h>
#include <stdio.h>
#include <string.h>
#include <stdbool.h>

// 颜色定义，用于美化输出
#define COLOR_GREEN   "\033[32m"
#define COLOR_BLUE    "\033[34m"
#define COLOR_RESET   "\033[0m"
#define COLOR_YELLOW  "\033[33m"
#define COLOR_CYAN    "\033[36m"
#define COLOR_MAGENTA "\033[35m"

// 打印测试标题
static void print_test_title(const char* title) {
    printf("\n%s===== %s 开始测试 =====%s\n", COLOR_BLUE, title, COLOR_RESET);
}

// 打印测试通过信息
static void print_test_pass(const char* msg) {
    printf("%s✓ 测试通过: %s%s\n", COLOR_GREEN, msg, COLOR_RESET);
}

// 打印向量内容的辅助函数
static void print_vector_status(const char* msg, vector_t* vec, void (*print_func)(void*)) {
    printf("%s%s: %s", COLOR_CYAN, msg, COLOR_RESET);
    vec_print(vec, print_func, COLOR_CYAN);
}

// --------------------------- 测试用数据类型定义 ---------------------------
// 1. 结构体类型
typedef struct {
    int id;
    char name[20];
    int age;
} Person;

// 2. 枚举类型
typedef enum {
    RED,
    GREEN,
    BLUE,
    YELLOW,
    PURPLE
} Color;

// 3. 联合体类型
typedef union {
    int int_val;
    float float_val;
    bool bool_val;
    char char_val;
} Variant;

// --------------------------- 打印函数定义 ---------------------------
// 打印整数
static void print_int(void* data) {
    if (data) {
        printf("%d", *(int*)data);
    } else {
        printf("NULL");
    }
}

// 打印Person结构体
static void print_person(void* data) {
    if (data) {
        Person* p = (Person*)data;
        printf("Person{id=%d, name='%s', age=%d}", p->id, p->name, p->age);
    } else {
        printf("NULL");
    }
}

// 打印Color枚举
static void print_color(void* data) {
    if (data) {
        Color c = *(Color*)data;
        const char* color_names[] = {"RED", "GREEN", "BLUE", "YELLOW", "PURPLE"};
        printf("%s", color_names[c]);
    } else {
        printf("NULL");
    }
}

// 打印Variant联合体
static void print_variant(void* data) {
    if (data) {
        Variant* v = (Variant*)data;
        // 为了演示，这里打印所有可能的值（实际使用中需要标记类型）
        printf("Variant{int=%d, float=%.1f, bool=%s, char='%c'}",
               v->int_val, v->float_val,
               v->bool_val ? "true" : "false", v->char_val);
    } else {
        printf("NULL");
    }
}

// --------------------------- 原有测试函数保持不变 ---------------------------
void push_back_test();
void insertion_test();
void deletion_test();
void util_test();

// --------------------------- 新添加的复杂类型测试函数 ---------------------------
/**
 * 测试结构体类型元素的向量操作
 */
void struct_test() {
    print_test_title("结构体类型元素测试");

    // 创建测试用结构体实例
    Person p1 = {1, "Alice", 25};
    Person p2 = {2, "Bob", 30};
    Person p3 = {3, "Charlie", 35};
    Person p4 = {4, "David", 40};

    // 初始化向量
    vector_t people;
    vec_new(&people);
    print_vector_status("初始化后的结构体向量", &people, print_person);

    // 测试插入操作
    vec_push_back(&people, &p1);
    vec_push_back(&people, &p2);
    print_vector_status("插入两个结构体后", &people, print_person);
    assert(vec_size(&people) == 2);
    print_test_pass("结构体元素插入");

    // 测试获取操作
    Person* get_p = (Person*)vec_get(&people, 0);
    assert(get_p->id == 1);
    assert(strcmp(get_p->name, "Alice") == 0);
    printf("%s获取第一个结构体: id=%d, name=%s%s\n",
           COLOR_CYAN, get_p->id, get_p->name, COLOR_RESET);
    print_test_pass("结构体元素获取");

    // 测试插入到指定位置
    vec_insert_at_index(&people, 1, &p3);
    print_vector_status("在位置1插入结构体后", &people, print_person);
    assert(vec_size(&people) == 3);
    assert(((Person*)vec_get(&people, 1))->id == 3);
    print_test_pass("结构体元素指定位置插入");

    // 测试修改操作
    vec_set(&people, 2, &p4);
    print_vector_status("修改位置2的结构体后", &people, print_person);
    assert(((Person*)vec_get(&people, 2))->id == 4);
    print_test_pass("结构体元素修改");

    // 测试删除操作
    vec_remove_from_index(&people, 0);
    print_vector_status("删除位置0的结构体后", &people, print_person);
    assert(vec_size(&people) == 2);
    print_test_pass("结构体元素删除");

    // 释放内存
    vec_free(&people);
}

/**
 * 测试枚举类型元素的向量操作
 */
void enum_test() {
    print_test_title("枚举类型元素测试");

    // 创建测试用枚举值
    Color c1 = RED;
    Color c2 = GREEN;
    Color c3 = BLUE;
    Color c4 = PURPLE;

    // 初始化向量
    vector_t colors;
    vec_new(&colors);
    print_vector_status("初始化后的枚举向量", &colors, print_color);

    // 测试插入操作
    vec_push_back(&colors, &c1);
    vec_push_back(&colors, &c2);
    vec_push_back(&colors, &c3);
    print_vector_status("插入三个枚举值后", &colors, print_color);
    assert(vec_size(&colors) == 3);
    print_test_pass("枚举元素插入");

    // 测试批量插入
    vec_insert_many_at_index(&colors, 1, 2, &c4, &c3);
    print_vector_status("批量插入枚举值后", &colors, print_color);
    assert(vec_size(&colors) == 5);
    print_test_pass("枚举元素批量插入");

    // 测试获取操作
    Color* get_c = (Color*)vec_get(&colors, 3);
    assert(*get_c == GREEN);
    // 修复：直接比较枚举值，而不是比较地址
    printf("%s获取位置3的枚举值: %s%s\n",
           COLOR_CYAN, *get_c == GREEN ? "GREEN" : "未知", COLOR_RESET);
    print_test_pass("枚举元素获取");

    // 测试删除操作
    vec_pop_back(&colors);
    print_vector_status("删除最后一个枚举值后", &colors, print_color);
    assert(vec_size(&colors) == 4);
    print_test_pass("枚举元素尾部删除");

    // 释放内存
    vec_free(&colors);
}

/**
 * 测试联合体类型元素的向量操作
 */
void union_test() {
    print_test_title("联合体类型元素测试");

    // 创建测试用联合体实例
    Variant v1 = {.int_val = 100};
    Variant v2 = {.float_val = 3.14f};
    Variant v3 = {.bool_val = true};
    Variant v4 = {.char_val = 'A'};

    // 初始化向量
    vector_t variants;
    vec_new(&variants);
    print_vector_status("初始化后的联合体向量", &variants, print_variant);

    // 测试插入操作
    vec_push_back(&variants, &v1);
    vec_push_back(&variants, &v2);
    print_vector_status("插入两个联合体后", &variants, print_variant);
    assert(vec_size(&variants) == 2);
    print_test_pass("联合体元素插入");

    // 测试向量合并
    vector_t variants2;
    vec_new(&variants2);
    vec_push_back(&variants2, &v3);
    vec_push_back(&variants2, &v4);
    print_vector_status("待合并的联合体向量", &variants2, print_variant);

    vec_push_back_vec(&variants, &variants2);
    print_vector_status("合并联合体向量后", &variants, print_variant);
    assert(vec_size(&variants) == 4);
    print_test_pass("联合体向量合并");

    // 测试批量删除
    vector_t removed;
    vec_new(&removed);
    vec_remove_many_from_index(&variants, 1, 2, &removed);
    print_vector_status("批量删除联合体后", &variants, print_variant);
    print_vector_status("被删除的联合体元素", &removed, print_variant);
    assert(vec_size(&variants) == 2);
    assert(vec_size(&removed) == 2);
    print_test_pass("联合体元素批量删除");

    // 释放内存
    vec_free(&variants);
    vec_free(&variants2);
    vec_free(&removed);
}

// --------------------------- 主函数 ---------------------------
int main() {
    printf("%s===== 向量库功能测试程序 =====%s\n", COLOR_YELLOW, COLOR_RESET);

    // 基础类型测试
    util_test();       // 工具函数测试
    push_back_test();  // 尾部插入测试
    insertion_test();  // 插入功能测试
    deletion_test();   // 删除功能测试

    // 复杂类型测试
    struct_test();     // 结构体类型测试
    enum_test();       // 枚举类型测试
    union_test();      // 联合体类型测试

    printf("\n%s所有测试均通过!%s\n", COLOR_GREEN, COLOR_RESET);
    return 0;
}

// --------------------------- 原有测试函数实现 ---------------------------
void push_back_test() {
    print_test_title("向量尾部插入功能");

    int a = 10;  // 测试用整数

    // 初始化向量
    vector_t vec;
    vec_new(&vec);
    print_vector_status("初始化后的向量", &vec, print_int);

    // 验证初始化状态
    assert(vec.array == NULL);
    assert(vec.size == 0);
    assert(vec_size(&vec) == 0);
    assert(vec.capacity == 0);
    print_test_pass("向量初始化状态正确");

    // 插入第一个元素
    vec_push_back(&vec, (void*)&a);
    print_vector_status("插入第一个元素后", &vec, print_int);
    assert(vec_size(&vec) == 1);
    assert(vec.capacity == 1);
    print_test_pass("插入第一个元素");

    // 插入第二个元素
    vec_push_back(&vec, (void*)&a);
    print_vector_status("插入第二个元素后", &vec, print_int);
    assert(vec_size(&vec) == 2);
    assert(vec.capacity == 2);
    print_test_pass("插入第二个元素");

    // 插入第三个元素（触发扩容）
    vec_push_back(&vec, (void*)&a);
    print_vector_status("插入第三个元素后", &vec, print_int);
    assert(vec_size(&vec) == 3);
    assert(vec.capacity == 4);  // 容量应翻倍为4
    print_test_pass("插入第三个元素（触发扩容）");

    // 创建另一个向量并插入6个元素
    vector_t new_vec;
    vec_new(&new_vec);
    for (int i = 0; i < 6; i++) {
        vec_push_back(&new_vec, (void*)&a);
    }
    print_vector_status("新建的源向量", &new_vec, print_int);

    // 合并两个向量
    vec_push_back_vec(&vec, &new_vec);
    print_vector_status("合并向量后", &vec, print_int);

    // 验证合并结果
    assert(vec_size(&new_vec) == 6);
    assert(new_vec.capacity == 8);  // 6个元素的扩容结果
    assert(vec_size(&vec) == 3 + 6);  // 原3个 + 新增6个
    assert(vec.capacity == 16);  // 合并后的扩容结果
    print_test_pass("向量合并插入功能");

    // 释放内存
    vec_free(&new_vec);
    vec_free(&vec);
    print_test_pass("向量内存释放");
}

void insertion_test() {
    print_test_title("向量插入功能");

    int b = 15;  // 测试用整数
    int a = 10;  // 测试用整数
    int index = 0;  // 插入位置

    // 初始化指定容量的向量
    vector_t vec;
    vec_new_cap(&vec, 2);
    print_vector_status("初始化指定容量的向量", &vec, print_int);

    // 验证初始化状态
    assert(vec_size(&vec) == 0);
    assert(vec.capacity == 2);
    print_test_pass("指定容量的向量初始化");

    // 插入4个元素（触发扩容）
    for (int i = 0; i < 4; i++) {
        vec_push_back(&vec, (void*)&a);
    }
    print_vector_status("插入4个元素后", &vec, print_int);

    // 在头部插入元素b
    assert(*((int*)vec_front(&vec)) == a);  // 插入前头部应为a
    vec_insert_at_index(&vec, index, (void*)&b);
    print_vector_status("在头部插入元素b后", &vec, print_int);

    // 验证插入结果
    assert(*((int*)vec_front(&vec)) == b);  // 插入后头部应为b
    assert(vec_size(&vec) == 5);
    assert(vec.capacity == 8);  // 扩容结果
    print_test_pass("在头部插入单个元素");

    // 更改插入位置并连续插入4个元素
    index = 3;
    for (int i = 0; i < 4; i++) {
        vec_insert_at_index(&vec, index, (void*)&b);
    }
    print_vector_status("在位置3插入4个b后", &vec, print_int);

    // 验证插入结果
    assert(*((int*)vec_get(&vec, index)) == b);
    assert(vec_size(&vec) == 9);
    assert(vec.capacity == 16);  // 再次扩容结果
    print_test_pass("在指定位置连续插入多个元素");

    // 测试批量插入功能
    int count = 3;
    vec_insert_many_at_index(&vec, index, count, &a, &b, &b);
    print_vector_status("批量插入3个元素后", &vec, print_int);

    // 验证批量插入结果
    assert(*((int*)vec_get(&vec, index)) == a);
    assert(*((int*)vec_get(&vec, index + 1)) == b);
    assert(*((int*)vec_get(&vec, index + 2)) == b);
    assert(vec_size(&vec) == 12);
    assert(vec.capacity == 16);  // 容量足够，无需扩容
    print_test_pass("批量插入元素功能");

    // 释放内存
    vec_free(&vec);
}

void deletion_test() {
    print_test_title("向量删除功能");

    int b = 15;  // 测试用整数
    int a = 10;  // 测试用整数
    int index = 0;  // 删除位置

    // 初始化向量并插入6个元素
    vector_t vec;
    vec_new(&vec);
    int values[] = {a, b, a, b, a, b};
    for (int i = 0; i < 6; i++) {
        vec_push_back(&vec, (void*)&values[i]);
    }
    print_vector_status("初始化并插入6个元素后", &vec, print_int);

    // 测试尾部删除
    assert(*((int*)vec_pop_back(&vec)) == b);  // 应删除最后一个元素b
    print_vector_status("第一次尾部删除后", &vec, print_int);
    assert(vec_size(&vec) == 5);
    assert(vec.capacity == 8);

    assert(*((int*)vec_pop_back(&vec)) == a);  // 再删除一个元素a
    print_vector_status("第二次尾部删除后", &vec, print_int);
    assert(vec_size(&vec) == 4);
    assert(vec.capacity == 4);  // 容量应缩减
    print_test_pass("尾部元素删除功能");

    // 补充两个元素
    vec_push_back(&vec, (void*)&a);
    vec_push_back(&vec, (void*)&b);
    print_vector_status("补充两个元素后", &vec, print_int);

    // 测试指定位置删除
    assert(*((int*)vec_remove_from_index(&vec, index)) == a);  // 删除头部元素a
    print_vector_status("删除头部元素后", &vec, print_int);
    assert(vec_size(&vec) == 5);
    print_test_pass("指定位置删除单个元素（头部）");

    // 更改删除位置
    index = 3;
    assert(*((int*)vec_remove_from_index(&vec, index)) == a);  // 删除指定位置元素
    print_vector_status("删除位置3的元素后", &vec, print_int);
    assert(vec_size(&vec) == 4);

    // 补充两个元素用于后续测试
    vec_insert_at_index(&vec, index, (void*)&a);
    vec_insert_at_index(&vec, index, (void*)&b);
    print_vector_status("补充两个元素后", &vec, print_int);
    print_test_pass("指定位置删除单个元素（中间）");

    // 测试批量删除
    index = 1;
    vector_t removed_elems;
    vec_new(&removed_elems);

    vec_remove_many_from_index(&vec, index, 3, &removed_elems);
    print_vector_status("批量删除3个元素后", &vec, print_int);
    print_vector_status("被删除的元素", &removed_elems, print_int);

    // 验证删除结果
    assert(vec_size(&removed_elems) == 3);
    assert(*((int*)removed_elems.array[0]) == a);
    assert(*((int*)removed_elems.array[1]) == b);
    assert(removed_elems.capacity == 4);  // 自动扩容结果

    assert(vec_size(&vec) == 3);
    assert(*((int*)vec_get(&vec, 1)) == a);
    print_test_pass("批量删除元素功能");

    // 释放内存
    vec_free(&removed_elems);
    vec_free(&vec);
}

void util_test() {
    print_test_title("向量工具函数");

    int b = 15;  // 测试用整数
    int a = 10;  // 测试用整数
    int index = 1;  // 测试位置

    // 初始化向量并插入6个元素
    vector_t vec;
    vec_new(&vec);
    int values[] = {a, b, a, b, a, b};
    for (int i = 0; i < 6; i++) {
        vec_push_back(&vec, (void*)&values[i]);
    }
    print_vector_status("初始化并插入6个元素后", &vec, print_int);

    // 测试获取元素功能
    assert(*((int*)vec_get(&vec, index)) == b);
    printf("%s获取位置%d的元素: %d (预期: %d)%s\n",
           COLOR_CYAN, index, *((int*)vec_get(&vec, index)), b, COLOR_RESET);
    print_test_pass("获取指定位置元素");

    // 测试设置元素功能
    vec_set(&vec, index, (void*)&a);
    print_vector_status("设置位置1的元素为a后", &vec, print_int);
    assert(*((int*)vec_get(&vec, index)) == a);
    print_test_pass("设置指定位置元素");

    // 测试获取大小功能
    assert(vec_size(&vec) == 6);
    printf("%s向量大小: %u (预期: 6)%s\n",
           COLOR_CYAN, vec_size(&vec), COLOR_RESET);
    print_test_pass("获取向量大小");

    // 释放内存
    vec_free(&vec);
}
